#include "Spark/Net/EventLoopThread.h"
#include <sys/prctl.h>

EventLoopThread::EventLoopThread(std::string threadName)
    : loop_(nullptr), loopThreadName_(std::move(threadName))
{
}

EventLoopThread::~EventLoopThread()
{
    run();
    if (loop_)
    {
        loop_->quit();
    }
    wait();
}

void EventLoopThread::wait()
{
    if (thread_->joinable())
    {
        thread_->join();
    }
}

EventLoop* EventLoopThread::run()
{
    if (started_)
        return nullptr;
    thread_.reset(new std::thread([this] { routine(); }));
    EventLoop* loop = nullptr;
    {
        std::unique_lock<std::mutex> l(mutex_);
        cond_.wait(l, [this] { return loop_ != nullptr; });
        loop = loop_;
    }
    started_ = true;
    return loop;
}

void EventLoopThread::routine()
{
    ::prctl(PR_SET_NAME, loopThreadName_.c_str());
    EventLoop loop;
    {
        std::unique_lock<std::mutex> l(mutex_);
        loop_ = &loop;
        cond_.notify_all();
    }
    loop.loop();
    loop_ = nullptr;
}
